package com.ybkj.o2o.zhuanxian.common;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class HttpClientUtil {

  private static String apikey = "63bdf7028579ff2c0ab44ff787f6efb1";

  private static String shortUrl = "http://apis.baidu.com/3023/shorturl/shorten";// 短链接生成


  private static String placeURL = "http://api.map.baidu.com/place/v2/search";

  private static String strSendURL = "http://api.map.baidu.com/geocoder/v2/";

  private static String directSendURL = "http://api.map.baidu.com/direction/v1/routematrix";

  private static  final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

  /**
   * .
   */
  private static String getAk() {
    List<String> aklist = new ArrayList<String>();
    aklist.add("AuNk3YS21DSmHEEvIFDf9dbD");
    // aklist.add("qUwI31Ww00t9ZEKkyQwQBwGW");
    // aklist.add("ROqEF3nPZEAAc2IXEvKhgB32");
    // aklist.add("v9IrYKFqyZogCUxc6cyegSld");
    // aklist.add("VGQdoQxhxtAb9ulMpODrDe53");
    // aklist.add("0uN3S7sy7ehZdsDm79qNtg71");
    // aklist.add("A0HgFu5ajp5KGoxoNeTL6IFr");
    // aklist.add("dSKScYEKSA9WrXX3GcMgVRg5");
    // aklist.add("pXoto9RTELxr1WN5zfoRawED");
    // aklist.add("t28R82dlBEniN6sndenOHCvb");
    // aklist.add("bMmmO1bxTXnW9SKrj0T9dcWt");
    // aklist.add("Bm3UQZegVky3xGaVQ1L9AdDR");
    // aklist.add("9TK4P0pIXOSA8F0FZNkiShqI");
    // aklist.add("dcrdrnjI8LgkiblWq39cktEF");
    // aklist.add("bexUsLb0vhLKPljWX18tq7xL");

    aklist.add("ZPSUvtssKbBN4vkQryCRZGWq");// 鲜艺 通过
    // aklist.add("8H1QBOhjG12uGXN5HZXxISVm");//肖浩 未通过
    aklist.add("BKhZw5iA5IU7OytHEdXTIUoH");// 杜伟 通过
    // aklist.add("1AhE1PSmqrn4juKa7AOh59fp");//熊鹏 未通过
    // aklist.add("fmdmjZ6XAh1G7elNGfGTQhMa");//张军 未通过

    Random rand = new Random();
    return aklist.get(rand.nextInt(aklist.size()));
  }

  /**
   * .
   */
  public static JSONArray getPlacesByName(String placeName, String cityName) {

    try {
      StringBuilder sb = new StringBuilder();
      sb.append(placeURL);
      sb.append("?output=").append("json");
      sb.append("&region=").append(cityName);
      sb.append("&q=").append(placeName);
      sb.append("&ak=").append(getAk());
      String content = getUrl(sb.toString());

      JSONObject obj = new JSONObject(content);

      if (obj.optInt("status") == 0) {

        JSONArray ret = obj.optJSONArray("results");
        return ret;

      }

      return null;
    } catch (Exception ex) {
      logger.error("getPlacesByName:{}",ex);
      return null;
    }
  }

  /**
   * .
   */
  public static String getPlaceByLngAndLat(Double lng, Double lat) {

    String street = "";
    String name = "";
    try {
      StringBuilder sb = new StringBuilder();
      sb.append("ak=").append(getAk());
      sb.append("&location=").append(lat).append(",").append(lng);
      sb.append("&output=").append("json");
      sb.append("&pois=").append(1);

      String result = getResponseDataById(strSendURL, sb.toString());

      JSONObject obj = new JSONObject(result);

      if (obj.optInt("status") == 0) {

        JSONObject ret = obj.optJSONObject("result");

        JSONObject addressComponent = ret.optJSONObject("addressComponent");
        street = addressComponent.optString("street");

        JSONArray pois = ret.optJSONArray("pois");
        JSONObject poi = pois.getJSONObject(0);
        name = poi.optString("name");

      }
    } catch (Exception ex) {
      logger.error("getPlaceByLngAndLat:{}",ex);
      return null;
    }

    if (StringUtils.isBlank(street) && StringUtils.isBlank(name)) {
      return "未知";
    } else {
      if (StringUtils.isBlank(street)) {
        return name;
      } else if (StringUtils.isBlank(name)) {
        return street;
      } else {
        return street + " " + name;
      }
    }

  }

  /**
   * .
   */
  public static String getCityByLngAndLat(Double lng, Double lat) {

    try {
      StringBuilder sb = new StringBuilder();
      sb.append("ak=").append(getAk());
      sb.append("&location=").append(lat ).append(",").append(lng);
      sb.append("&output=").append("json");
      sb.append("&pois=").append(0);

      String result = getResponseDataById(strSendURL, sb.toString());

      JSONObject obj = new JSONObject(result);

      System.out.println(obj);

      if (obj.optInt("status") == 0) {

        JSONObject ret = obj.optJSONObject("result");

        JSONObject addressComponent = ret.optJSONObject("addressComponent");
        return addressComponent.optString("city");
      }
    } catch (Exception ex) {
      logger.error("getCityByLngAndLat:{}",ex);
    }

    return "";
  }

  /**
   * .
   */
  public static Result<Map<String, Double>> getLngAndLatByPlace(String address, String city) {

    Result<Map<String, Double>> vo = new Result<Map<String, Double>>();

    StringBuilder sb = new StringBuilder();
    sb.append("ak=").append(getAk());
    sb.append("&address=").append(address);
    sb.append("&city=").append(city);
    sb.append("&output=").append("json");

    try {
      String result = getResponseDataById(strSendURL, sb.toString());

      JSONObject obj = new JSONObject(result);

      Map<String, Double> map = new HashMap<String, Double>();
      if ("0".equals(obj.get("status").toString())) {

        map.put(
            "lng",
            Double.valueOf(obj.getJSONObject("result").getJSONObject("location").get("lng")
                .toString()));
        map.put(
            "lat",
            Double.valueOf(obj.getJSONObject("result").getJSONObject("location").get("lat")
                .toString()));

        vo.setSuccess(true);
        vo.setResult(map);
        return vo;
      }

      vo.setSuccess(false);
      return vo;

    } catch (Exception ex) {
      vo.setSuccess(false);
      logger.error("getLngAndLatByPlace:{}",ex);
      return vo;
    }
  }

  /**
   * .
   */
  public static String getTimeByTwoPoints(
      Double fromlng, Double fromlat, Double tolng, Double tolat) {

    StringBuilder sb = new StringBuilder();
    sb.append(directSendURL);
    sb.append("?output=").append("json");
    sb.append("&origins=").append(fromlat).append(",").append(fromlng);
    sb.append("&destinations=").append(tolat).append(",").append(tolng);
    sb.append("&ak=").append(getAk());

    String content = getUrl(sb.toString());

    if (null != content) {

      JSONObject obj = new JSONObject(content);

      if ("0".equals(obj.get("status").toString())) {

        JSONObject result = obj.optJSONObject("result");

        if (result != null) {
          JSONArray elements = result.optJSONArray("elements");
          if (elements != null && elements.length() > 0) {
            JSONObject element = elements.optJSONObject(0);
            JSONObject duration = element.optJSONObject("duration");
            int durationValue = duration.optInt("value");

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.SECOND, durationValue);

            return DateFormatUtils.format(calendar, "MM-dd HH:mm");
          }
        }
      }
    }

    return "";
  }

  /**
   * .
   */
  public static String urlEncodeUtf8(String source) {
    String result = source + "wx/v1/memberOrder";
    try {
      result = java.net.URLEncoder.encode(source, "utf-8");
    } catch (UnsupportedEncodingException ex) {
      logger.error("urlEncodeUTF8:{}",ex);
    }
    return result;
  }

  /**
   * .
   */
  public static String getUserInfo(String code, String appId, String secret) {
    String getcodeRequest =
        "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret
            + "&code=" + code + "&grant_type=authorization_code";
    String info = getUrl(getcodeRequest);

    try {
      if (StringUtils.isNotBlank(info)) {
        JSONObject obj = new JSONObject(info);
        Object openidObj = obj.get("openid");
        if (null != openidObj) {
          String openId = obj.getString("openid");
          return openId;
        }
      }
    } catch (JSONException ex) {
      // e.printStackTrace();
      logger.error("getUserInfo:{}",ex);
    }
    return "";
  }

  /**
   * .
   */
  public static String getHaMTimeByTwoPoints(Double fromlng, Double fromlat, Double tolng,
      Double tolat) {

    StringBuilder sb = new StringBuilder();
    sb.append(directSendURL);
    sb.append("?output=").append("json");
    sb.append("&origins=").append(fromlat + "," + fromlng);
    sb.append("&destinations=").append(tolat + "," + tolng);
    sb.append("&ak=").append(getAk());

    String result = getUrl(sb.toString());

    JSONObject obj = new JSONObject(result);

    if (obj.get("status").toString().equals("0")) {
      Integer durationValue =
          Integer.valueOf(obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
              .getJSONObject("duration").get("value").toString());
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(new Date());
      if (null != durationValue) {
        calendar.add(Calendar.SECOND, durationValue);
      }
      Date arriveTime = calendar.getTime();

      SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
      String dateStr = sdf.format(arriveTime);
      return dateStr;
    }

    return "";
  }

  /**
   * .
   */
  public static Date getDateByTwoPoints(
      Double fromlng, Double fromlat, Double tolng, Double tolat) {

    StringBuilder sb = new StringBuilder();
    sb.append(directSendURL);
    sb.append("?output=").append("json");
    sb.append("&origins=").append(fromlat).append( ",").append(fromlng);
    sb.append("&destinations=").append(tolat).append( ",").append(tolng);
    sb.append("&ak=").append(getAk());

    String result = getUrl(sb.toString());

    JSONObject obj = new JSONObject(result);

    if (obj.get("status").toString().equals("0")) {

      if (obj.optJSONObject("result") != null) {
        Integer durationValue =
            Integer.valueOf(obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
                .getJSONObject("duration").get("value").toString());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (null != durationValue) {
          calendar.add(Calendar.SECOND, durationValue);
        }
        Date arriveTime = calendar.getTime();

        return arriveTime;
      }

      return null;

    }

    return null;
  }

  /**
   * .
   */
  public static String getDistanceAndTimeByTwoPoints(Double fromlng, Double fromlat, Double tolng,
      Double tolat) {

    StringBuilder sb = new StringBuilder();
    sb.append(directSendURL);
    sb.append("?output=").append("json");
    sb.append("&origins=").append(fromlat).append(",") .append(fromlng);
    sb.append("&destinations=").append(tolat ).append(",") .append(tolng);
    sb.append("&ak=").append(getAk());

    String result = getUrl(sb.toString());

    JSONObject obj = new JSONObject(result);

    if (obj.get("status").toString().equals("0")) {
      String distanceTxt =
          obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
              .getJSONObject("distance").get("text").toString();
      Integer durationValue =
          Integer.valueOf(obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
              .getJSONObject("duration").get("value").toString());
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(new Date());
      if (null != durationValue) {
        calendar.add(Calendar.SECOND, durationValue);
      }
      Date arriveTime = calendar.getTime();

      SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
      String dateStr = sdf.format(arriveTime);
      return dateStr + " 行程" + distanceTxt;
    }

    return "";
  }

  /**
   * .
   */
  public static Result<Map<String, Long>> getDistanceAndTimeValueByTwoPoints(Double fromlng,
      Double fromlat, Double tolng, Double tolat) {

    Result<Map<String, Long>> vo = new Result<Map<String, Long>>();

    StringBuilder sb = new StringBuilder();
    sb.append(directSendURL);
    sb.append("?output=").append("json");
    sb.append("&origins=").append(fromlat) .append(",").append(fromlng);
    sb.append("&destinations=").append(tolat).append( ",") .append(tolng);
    sb.append("&ak=").append(getAk());

    try {
      String result = getUrl(sb.toString());

      JSONObject obj = new JSONObject(result);

      Map<String, Long> map = new HashMap<String, Long>();

      if (obj.get("status").toString().equals("0")) {
        Long distanceValue =
            Long.valueOf(obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
                .getJSONObject("distance").get("value").toString());
        Long durationValue =
            Long.parseLong(obj.getJSONObject("result").getJSONArray("elements").getJSONObject(0)
                .getJSONObject("duration").get("value").toString());

        map.put("distance", distanceValue);// 米
        map.put("time", durationValue);// 秒
        vo.setResult(map);
        vo.setSuccess(true);

        return vo;
      } else {
        vo.setSuccess(false);
        return vo;
      }

    } catch (Exception ex) {
      logger.error("getDistanceAndTimeValueByTwoPoints:{}",ex);
      vo.setSuccess(false);
      return vo;
    }
  }

  /**
   * .
   */
  public static JsonCheckStatus checkLogin(String url) {
    String result = getUrl(url);

    JSONObject obj = new JSONObject(result);

    JsonCheckStatus jcs = new JsonCheckStatus();

    if (obj.optBoolean("success")) {
      jcs.setSuccess(true);
      jcs.setStatus(obj.optString("status"));
      jcs.setPuaseTimeStamp(Long.parseLong(obj.optString("puaseTimeStamp")));
      jcs.setFee(obj.optDouble("fee"));
      jcs.setPuaseTime(obj.optString("puaseTime"));
      jcs.setMemo(obj.optString("memo"));
    } else {
      jcs.setSuccess(false);
    }
    return jcs;
  }

  /**
   * .
   */
  public static Long getSmsCount(String url) {
    String result = getUrl(url);

    return Long.parseLong(result);

  }

  /**
   * .
   */
  public static String debtsPay(String url) {
    String result = getUrl(url);

    return result;

  }

  /**
   * .
   */
  public static String getShortUrl(String httpArg) throws UnsupportedEncodingException {
    BufferedReader reader = null;
    String result = null;
    StringBuilder sbf = new StringBuilder();
    String httpUrl = shortUrl + "?url_long=" + URLEncoder.encode(
            httpArg,StandardCharsets.UTF_8.name());

    try {
      URL url = new URL(httpUrl);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      connection.setRequestMethod("GET");
      // 填入apikey到HTTP header
      connection.setRequestProperty("apikey", apikey);
      connection.connect();
      InputStream is = connection.getInputStream();
      reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8.name()));
      String strRead = null;
      while ((strRead = reader.readLine()) != null) {
        sbf.append(strRead);
        sbf.append("\r\n");
      }
      reader.close();
      result = sbf.toString();

      JSONObject obj = new JSONObject(result);
      JSONArray urls = obj.getJSONArray("urls");
      JSONObject urls1 = urls.getJSONObject(0);
      if (urls1.optBoolean("result")) {
        return urls1.optString("url_short");
      } else {
        return result;
      }
    } catch (Exception ex) {
      logger.error("getShortUrl:{}",ex);
      ex.printStackTrace();
      return "";
    }

  }


  private static String getResponseDataById(String url, String postData) {
    String data = null;
    try {
      URL dataUrl = new URL(url);
      HttpURLConnection con = (HttpURLConnection) dataUrl.openConnection();
      con.setRequestMethod("GET");
      con.setRequestProperty("Proxy-Connection", "Keep-Alive");
      con.setDoOutput(true);
      con.setDoInput(true);

      OutputStream os = con.getOutputStream();
      DataOutputStream dos = new DataOutputStream(os);
      if (StringUtils.isNotBlank(postData)) {
        dos.write(postData.getBytes(StandardCharsets.UTF_8.name()));
      }
      dos.flush();
      dos.close();

      InputStream is = con.getInputStream();
      data = IOUtils.toString(is, "utf-8");
      IOUtils.closeQuietly(is);
      con.disconnect();
    } catch (Exception ex) {
      logger.error("GetResponseDataByID:{}",ex);
    }
    return data;
  }

  private static String postResponseDataById(String url, String postData) {
    String data = null;
    try {
      URL dataUrl = new URL(url);
      HttpURLConnection con = (HttpURLConnection) dataUrl.openConnection();
      con.setRequestMethod("POST");
      con.setRequestProperty("Proxy-Connection", "Keep-Alive");
      con.setDoOutput(true);
      con.setDoInput(true);

      OutputStream os = con.getOutputStream();
      DataOutputStream dos = new DataOutputStream(os);
      if (StringUtils.isNotBlank(postData)) {
        dos.write(postData.getBytes(StandardCharsets.UTF_8.name()));
      }
      dos.flush();
      dos.close();

      InputStream is = con.getInputStream();
      data = IOUtils.toString(is, "utf-8");
      IOUtils.closeQuietly(is);
      con.disconnect();
    } catch (Exception ex) {
      logger.error("PostResponseDataByID:{}",ex);
    }
    return data;
  }

  private static String getUrl(String url) {

    String result = null;// 访问返回结果

    InputStream in = null;
    try {
      // 创建url
      URL realurl = new URL(url);
      // 打开连接
      URLConnection connection = realurl.openConnection();
      // 设置通用的请求属性
      connection.setRequestProperty("accept", "*/*");
      connection.setRequestProperty("connection", "Keep-Alive");
      connection.setRequestProperty("user-agent",
          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
      // 建立连接
      connection.connect();
      in = connection.getInputStream();
      result = IOUtils.toString(in, "UTF-8");
    } catch (IOException ex) {
      logger.error("getUrl:{}",ex);
    } finally {
      IOUtils.closeQuietly(in);
    }

    return result;

  }


  /*
   * public static void main(String[] args) { try { StringBuilder sb = new StringBuilder();
   * sb.append("ak=").append("1AhE1PSmqrn4juKa7AOh59fp"); sb.append("&location=").append("123" + ","
   * + "123"); sb.append("&output=").append("json"); sb.append("&pois=").append(0);
   * 
   * String result = GetResponseDataByID(strSendURL, sb.toString());
   * 
   * JSONObject obj = new JSONObject(result);
   * 
   * System.out.println(obj); if (obj.optInt("status") == 0) {
   * 
   * 
   * } } catch (Exception e) { e.printStackTrace(); } }
   */

}
